package com.decade.qiyeshapan.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.decade.qiyeshapan.entity.Order;
import com.decade.qiyeshapan.model.ApiResponse;
import com.decade.qiyeshapan.config.RedisKeyManager;

@Service
public class GameService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private MessageService messageService;

    // 修改后的全局进度计算方法
    public int getGameProgress(String gameId) {
        // 获取所有玩家列表（需要先实现获取游戏玩家列表的方法）
        Set<Object> players = redisTemplate.opsForSet().members(RedisKeyManager.gamePlayers(gameId));

        // 获取所有玩家进度（包含未保存进度的玩家）
        return players.stream()
                .mapToInt(username -> {
                    Object progress = redisTemplate.opsForHash().get(RedisKeyManager.gameProgress(gameId), username);
                    return progress != null ? Integer.parseInt(progress.toString()) : 0;
                })
                .min()
                .orElse(0);
    }

    public void updatePlayerProgress(String gameId, String username, int progress) {
        // 保存玩家进度
        redisTemplate.opsForHash().put(RedisKeyManager.gameProgress(gameId), username, String.valueOf(progress));

        // 获取最新全局进度
        int globalProgress = getGameProgress(gameId);

        // 保存全局进度
        redisTemplate.opsForValue().set(RedisKeyManager.globalProgress(gameId), String.valueOf(globalProgress));
    }

    // 需要添加的玩家管理方法（在用户加入游戏时调用）
    public void addPlayerToGame(String gameId, String username) {
        redisTemplate.opsForSet().add(RedisKeyManager.gamePlayers(gameId), username);
        // 初始化玩家进度为0
        redisTemplate.opsForHash().putIfAbsent(RedisKeyManager.gameProgress(gameId), username, "0");
    }

    private Set<String> getAdRanking(String gameId) {
        // 确保广告费数据按以下格式存储
        String adKey = RedisKeyManager.adRanking(gameId, "本地", "P1"); 
        // 示例：ZADD ad:testGame:本地:P1 5000 用户1 3000 用户2
        return redisTemplate.opsForZSet()
            .reverseRange(adKey, 0, -1)
            .stream()
            .map(Object::toString)
                .collect(Collectors.toCollection(LinkedHashSet::new));
    }



    public ApiResponse getAvailableOrders(String gameId) {


        // 获取所有订单
        List<Order> currentQuarterOrders = getCurrentQuarterOrders(gameId);

        // 获取所有用户已选订单
        Set<String> userOrderKeys = redisTemplate.keys(RedisKeyManager.userOrders(gameId, "*"));
        Set<Object> selectedOrders = new HashSet<>();
        
        if (userOrderKeys != null) {
            for (String key : userOrderKeys) {
                selectedOrders.addAll(redisTemplate.opsForSet().members(key));
            }
        }
        
        // 过滤已选订单
        Set<Object> availableOrders = new HashSet<>(currentQuarterOrders.stream().map(Order::getOrderId).collect(Collectors.toList()));
        availableOrders.removeAll(selectedOrders);

        // 转换并返回订单数据
        List<Order> filteredOrders = availableOrders.stream()
            .map(id -> {
                Map<Object, Object> orderMap = redisTemplate.opsForHash().entries(RedisKeyManager.orderKey(id.toString()));
                return BeanUtil.mapToBean(orderMap, Order.class, true);
            })
            .filter(Objects::nonNull)
            .collect(Collectors.toList());

        // 保持原有轮次逻辑
        Long currentTurn = redisTemplate.opsForValue().increment(RedisKeyManager.gameTurn(gameId), 0);
        Set<String> userRanking = getAdRanking(gameId);
        int currentIndex = (int) (currentTurn % userRanking.size());
        String currentUser = userRanking.stream().skip(currentIndex).findFirst().orElse(null);

        Map<String, Object> result = new HashMap<>();
        result.put("orders", filteredOrders);
        result.put("currentUser", currentUser);
        result.put("currentTurn", currentTurn);
        
        return ApiResponse.success(result);
    }

    // 选中订单
    public ApiResponse selectOrder(String gameId, String orderId, String username) {
        System.out.println("当前请求用户：" + username);
        // 修改类型转换方式
        Long currentTurn = ((Number) redisTemplate.opsForValue().get(RedisKeyManager.gameTurn(gameId))).longValue();
        
        // 保持其他逻辑不变
        Set<String> userRanking = getAdRanking(gameId);
        int currentIndex = (int) (currentTurn % userRanking.size());
        String currentUser = userRanking.stream().skip(currentIndex).findFirst().orElse(null);
        System.out.println("计算出的应选用户：" + currentUser);
        System.out.println("广告排名列表：" + userRanking);
        System.out.println("当前轮次索引：" + currentTurn);

        if (!username.equals(currentUser)) {
            return ApiResponse.error(403, "当前不是您的选择轮次");
        }

        // 修改返回值处理
//        Long removedCount = redisTemplate.opsForSet().remove("game:available-orders:" + gameId, orderId);
//        if (removedCount != null && removedCount > 0) {
//            redisTemplate.opsForSet().add("user:orders:" + username + ":" + gameId, orderId);
//            redisTemplate.opsForValue().increment("game:turn:" + gameId, 1);
//            return ApiResponse.success("选单成功");
//        }
//        return ApiResponse.error(404, "订单不存在或已被选择");

        redisTemplate.opsForSet().add(RedisKeyManager.userOrders(gameId, username), orderId);
        redisTemplate.opsForValue().increment(RedisKeyManager.gameTurn(gameId), 1);

        // 通知所有用户 刷新订单列表的数据
        JSONObject msg = JSONUtil.createObj()
                .set("type", "orderUpdate");
        messageService.broadcastToGame(gameId, msg.toString());
        return ApiResponse.success("选单成功");
    }

    private List<Order> getCurrentQuarterOrders(String gameId) {
        String gameKey = RedisKeyManager.gameInfo(gameId);
        Map<Object, Object> gameInfo = redisTemplate.opsForHash().entries(gameKey);
        int currentYear = (Integer) gameInfo.get("currentYear");
        int currentQuarter = (Integer) gameInfo.get("currentQuarter");

        return redisTemplate.keys("order:*").stream()
            .map(key -> BeanUtil.mapToBean(redisTemplate.opsForHash().entries(key), Order.class, true))
            .filter(order -> order.getYear() == currentYear && order.getQuarter() == currentQuarter)
            .collect(Collectors.toList());
    }
}
